<template>
    <el-table
            ref="multipleTableRef"
            :data="data"
            style="width: 100%"
            row-key="id"
            :border="config.border"
            :stripe="config.stripe"
            :lazy="config.lazy"
            :tree-props="defaultProps"
            :row-class-name="rowClassName"
            :header-row-class-name="headerClassName"
            select-on-indeterminate
            @select-all="selectAll"
            @row-click="rowClick"
            @select="selectChange"
    >
        <el-table-column v-if="config.selection" type="selection" width="40"/>
        <el-table-column v-if="config.index" type="index" prop="编号"/>
        <template v-for="(item,index) in title" :key="index">
            <template v-if="item.columnType!='edit'">
                <el-table-column v-if="item.visible==true" :prop="item.prop" :label="item.label"
                                 :sortable="item.sortable"
                                 :width="flexColumnWidth(item.prop, data)"
                >
                    <!--自定义表格内容，这里是向element组件传递插槽-->
                    <template #default="scope">
                        <template v-if="item.columnType=='btn'">
                            <el-button size="small" @click="handleEdit(scope.$index, scope.row)" @click.stop="rowClick">
                                {{scope.row[item.prop]}}
                            </el-button>
                        </template>
                        <template v-else-if="item.columnType=='icon'">
                            <el-icon :size="20" @click.stop="rowClick">
                                <i :class="scope.row[item.prop]"></i>
                            </el-icon>
                        </template>
                        <template v-else-if="item.columnType=='input'">
                            <el-input v-model="scope.row[item.prop]" @click.stop="rowClick"
                                      @blur="blur(scope.row,item.prop)">
                            </el-input>
                        </template>
                        <template v-else-if="item.columnType=='switch'">
                            <el-switch v-model="scope.row[item.prop]"
                                       class="ml-2"
                                       active-color="var(--el-color-success)"
                                       inactive-color="var(--el-color-info)"
                                       @click.stop="rowClick"
                                       @change="(val)=>{changeStat(scope.row,item.prop, val)}"/>
                        </template>
                        <template v-else-if="item.columnType=='image'">
                            <el-image style="width: 100px; height: 100px"
                                      :src="scope.row[item.prop]"
                                      @click="scale(item.prop)"
                                      fit="cover" @click.stop="rowClick"></el-image>
                        </template>
                        <template v-else>
                            {{scope.row[item.prop]}}
                        </template>
                    </template>
                </el-table-column>
            </template>
            <template v-else>
                <el-table-column
                        v-if="item.visible==true"
                        :prop="item.prop"
                        :label="item.label"
                        :sortable="item.sortable"
                        :width="item.width"
                        fixed="right">
                    <template #default="scope" :prop="item.prop" :label="item.label">
                        <el-button-group @click.stop="rowClick">
                            <!--在slot外部包裹上span可以 绑定事件，但不灵活-->
                            <slot name="add" :item="{...scope.row}"></slot>
                            <slot name="edit" :item="{...scope.row}"></slot>
                            <slot name="detail" :item="{...scope.row}"></slot>
                            <slot name="del" :item="{...scope.row}"></slot>
                        </el-button-group>
                    </template>
                </el-table-column>
            </template>
        </template>
    </el-table>

    <!--缩放图片-->
    <dialog-img v-model="dialogVisible" :data="data" :srcField="srcField"></dialog-img>

    <!--操作模块-->
    <Dialog v-model:visible="visible"></Dialog>

</template>

<script lang="ts">
    import {defineComponent, provide, ref, watch} from 'vue'

    import tHooks from "@/hooks/TreeHooks.js"
    import lodash from "lodash"
    import DialogImg from "@/components/DialogImg.vue";
    import Dialog from "@/components/Dialog.vue"

    export default defineComponent({
        name: "TableTree",
        props: {
            title: {
                type: Object,
                default: () => {
                    return {
                        data: {
                            type: Array,
                            default: () => {
                                return []
                            }
                        },
                        refresh: Object
                    }
                }
            },
            data: {
                type: Array,
                default: () => {
                    return [];
                }
            },
            config: {
                type: Object,
                default: () => {
                    return {
                        border: true,		//边框
                        stripe: true,		//斑马纹
                        selection: true,	//是否可全选
                        index: false,		//索引
                        lazy: false,          //懒加载
                    };
                }
            },
            row: {
                type: Object,
                default: () => {
                    return {}
                }
            }
        },
        components: {DialogImg, Dialog},
        setup(props) {
            //配置
            const defaultProps = {
                children: 'child',  //先绑定props
            }

            /***************************************************图片缩放*************************************************/
            const dialogVisible = ref(false);
            const srcField = ref();
            //缩放图片
            const scale = (val) => {
                dialogVisible.value = true
                srcField.value = val
            }
            /***************************************************图片缩放*************************************************/


            /***************************************************勾选功能*************************************************/
                //勾选功能
            const {
                    getInitRelation,
                    selectStatus,
                    choice,
                    selectNum,
                    choiceAll,
                } = tHooks(defaultProps.children);

            let InitRelation = {}
            //实际上只有一次
            watch(() => props.data, (val) => {
                InitRelation = getInitRelation(val);
            })

            console.log(selectStatus);

            //单独勾选  勾选时2值都返回,取消勾选时只返回row
            const selectChange = (selection, row) => {
                choice(row)
            }

            //row-class-name 属性来为 Table 中的某一行添加 class, 表明该行处于某种状态。
            const rowClassName = (obj) => {
                for (let key in selectNum) {
                    if (obj.row.id == key) {
                        if (selectNum[key] == 0) {
                            return 'cancel'
                        } else {
                            if (selectNum[key] == InitRelation[key]) {
                                return 'checked'
                            } else {
                                return 'indeterminate'
                            }
                        }
                    }
                }
            }

            //表头
            const headerClassName = (obj) => {
                //直接对比数量
                if (obj.rowIndex == 0) {
                    let cNum = lodash.sum(lodash.values(selectNum));
                    if (0 == cNum) {
                        return 'cancel'
                    }

                    let aNum = lodash.sum(lodash.values(InitRelation));
                    if (cNum < aNum) {
                        return 'indeterminate'
                    }

                    if (cNum == aNum) {
                        return 'checked1'
                    }
                }
            }

            //全选
            const selectAll = () => {
                choiceAll()
            }

            //行方法
            const rowClick = (row) => {
                choice(row)
            }
            /***************************************************勾选功能*************************************************/


            /*============================================操作功能============================================*/
            const visible = ref(false);
            watch(() => props.row.id, () => {
                visible.value = true; //显示不显示
            })

            //弹窗内容
            provide('dialog', props.row);


            //input 失焦
            const blur = (row, key) => {
                let data: any = {}
                data.id = row.id
                data[key] = row[key]
                props.row.reset(data)
            }

            //修改状态
            const changeStat = (row, key, val) => {
                let data: any = {}
                data.id = row.id
                data[key] = val == true ? 1 : 0
                props.row.reset(data)
            }


            // 自适应表格列宽
            const flexColumnWidth = (str, tableData, flag = 'max') => {
                // str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
                // flag为可选值，可不传该参数,传参时可选'max'或'equal',默认为'max'
                // flag为'max'则设置列宽适配该列中最长的内容,flag为'equal'则设置列宽适配该列中第一行内容的长度。
                let columnContent = ''
                if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
                    return
                }
                if (!str || !str.length || str.length === 0 || str === undefined) {
                    return
                }
                if (flag === 'equal') {
                    // 获取该列中第一个不为空的数据(内容)
                    for (let i = 0; i < tableData.length; i++) {
                        if (tableData[i][str].length > 0) {
                            columnContent = tableData[i][str]
                            break
                        }
                    }
                } else {
                    // 获取该列中最长的数据(内容)
                    let index = 0
                    for (let i = 0; i < tableData.length; i++) {
                        if (tableData[i][str] === null) {
                            return 100
                        }
                        const now_temp = tableData[i][str]
                        const max_temp = tableData[index][str]
                        if (now_temp.length >= max_temp.length) {
                            index = i
                        }
                    }

                    columnContent = tableData[index][str].toString()
                }
                // 以下分配的单位长度可根据实际需求进行调整
                let flexWidth = 0
                for (const char of columnContent) {
                    if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
                        // 如果是英文字符，为字符分配8个单位宽度
                        flexWidth += 8
                    } else if (char >= '\u4e00' && char <= '\u9fa5') {
                        // 如果是中文字符，为字符分配18个单位宽度
                        flexWidth += 18
                    } else {
                        // 其他种类字符，为字符分配15个单位宽度
                        flexWidth += 15
                    }
                }
                if (flexWidth < 120) {
                    // 设置最小宽度
                    flexWidth = 120
                }
                return flexWidth
            }


            /*============================================操作功能============================================*/
            return {
                defaultProps,
                scale,
                srcField,
                selectChange,
                rowClassName,
                headerClassName,
                selectAll,
                rowClick,
                dialogVisible,
                visible,
                blur,
                changeStat,
                flexColumnWidth
            }
        },
    })
</script>

<style lang='scss'>
    .img-dialog {
        background-color: transparent;
    }

    .indeterminate {
        .el-checkbox__input {
            .el-checkbox__inner {
                background-color: var(--el-checkbox-checked-bg-color);
                border-color: var(--el-checkbox-checked-input-border-color);

                &::after {
                    border-color: #C0C4CC !important;
                    content: "";
                    position: absolute;
                    display: block;
                    background-color: #fff;
                    height: 2px;
                    transform: scale(0.5);
                    left: 0;
                    right: 0;
                    top: 5px;
                    width: auto !important;
                }
            }
        }
    }

    .checked {
        .el-checkbox__input {
            .el-checkbox__inner {
                background-color: var(--el-checkbox-checked-bg-color);
                border-color: var(--el-checkbox-checked-input-border-color);

                &::after {
                    background-color: var(--el-checkbox-checked-bg-color);
                    box-sizing: content-box;
                    content: "";
                    border: 1px solid var(--el-checkbox-checked-icon-color);
                    border-left: 0;
                    border-top: 0;
                    height: 7px;
                    left: 4px;
                    position: absolute;
                    top: 1px;
                    transform: rotate(45deg) scaleY(1);
                    width: 3px;
                    transition: transform .15s ease-in 50ms;
                    transform-origin: center;
                }
            }
        }
    }

    .checked1 {
        .el-checkbox__input {
            .el-checkbox__inner {
                background-color: var(--el-checkbox-checked-bg-color);
                border-color: var(--el-checkbox-checked-input-border-color);

                &::before {
                    background-color: var(--el-checkbox-checked-bg-color);
                    box-sizing: content-box;
                    content: "";
                    border: 1px solid var(--el-checkbox-checked-icon-color);
                    border-left: 0;
                    border-top: 0;
                    height: 7px;
                    left: 4px;
                    position: absolute;
                    top: 1px;
                    transform: rotate(45deg) scaleY(1);
                    width: 3px;
                    transition: transform .15s ease-in 50ms;
                    transform-origin: center;
                    z-index: 9999;
                }
            }
        }
    }

    .cancel {
        .el-checkbox__input {
            .el-checkbox__inner {
                background-color: var(--el-checkbox-bg-color);
                border: var(--el-checkbox-input-border);

                &::after {
                    box-sizing: content-box;
                    content: "";
                    border: 1px solid var(--el-checkbox-checked-icon-color);
                    border-left: 0;
                    border-top: 0;
                    height: 7px;
                    left: 4px;
                    position: absolute;
                    top: 1px;
                    transform: rotate(45deg) scaleY(0);
                    width: 3px;
                    transition: transform .15s ease-in 50ms;
                    transform-origin: center;
                }
            }
        }
    }
</style>